package multi_thread.advanced;

import sun.misc.Unsafe;

import java.util.Arrays;

/**
 * @author Cheng Jun
 * Description: 练习 Unsafe 操作 Array类型变量
 * @version 1.0
 * @date 2021/9/29 20:01
 */
public class UnsafeArrayExample {

    private int[] salary = {4000, 6500, 10000};

    public static void main(String[] args) throws NoSuchFieldException {
        UnsafeArrayExample unsafeArrayExample = new UnsafeArrayExample();
        Unsafe theUnsafe = UnsafeUtil.theUnsafe();
        // 数组元素中第一个元素的地址
        int baseOffset = theUnsafe.arrayBaseOffset(int[].class);
        // int 所占的字节数大小
        int indexScale = theUnsafe.arrayIndexScale(int[].class);
        System.out.println("theUnsafe.arrayBaseOffset(int[].class) ===> baseOffset = " + baseOffset);
        System.out.println("theUnsafe.arrayIndexScale(int[].class) ===> indexScale = " + indexScale);

        // 使用 salary数组的偏移地址，则修改的是 数组本身
        long salaryOffset = theUnsafe.objectFieldOffset(unsafeArrayExample.getClass().getDeclaredField("salary"));
        System.out.println("salary = " + Arrays.toString(unsafeArrayExample.salary));
        theUnsafe.putObject(unsafeArrayExample, salaryOffset, new int[]{1, 2, 3});
        System.out.println("theUnsafe.putObject ===> salary = " + Arrays.toString(unsafeArrayExample.salary));

        theUnsafe.putInt(unsafeArrayExample.salary, (long) (baseOffset + 0 * indexScale), 4300);
        System.out.println("theUnsafe.putInt(unsafeArrayExample.salary, (long)baseOffset + 0 * indexScale, 4300) ===> salary = " +
                Arrays.toString(unsafeArrayExample.salary));

        theUnsafe.putInt(unsafeArrayExample.salary, (long) (baseOffset + 1 * indexScale), 7000);
        System.out.println("theUnsafe.putInt(unsafeArrayExample.salary, (long)baseOffset + 1 * indexScale, 7000) ===> salary = " +
                Arrays.toString(unsafeArrayExample.salary));

        theUnsafe.putInt(unsafeArrayExample.salary, (long) baseOffset + 10 * indexScale, 7000);
        System.out.println("theUnsafe.putInt(unsafeArrayExample.salary, (long)baseOffset + 10 * indexScale, 7000) " +
                "不会自动扩容");

        // CAS 用法练习
        theUnsafe.compareAndSwapInt(unsafeArrayExample.salary, (long) baseOffset + 2 * indexScale, 3, 12000);
        System.out.println("theUnsafe.compareAndSwapInt(unsafeArrayExample.salary, (long) baseOffset + 2 * indexScale, 3, 12000) ===> " +
                Arrays.toString(unsafeArrayExample.salary));
    }
}
